package kd.xkqj.unittest.plugin.model;

import java.util.ArrayList;
import java.util.List;

/**
 * @description: 辅助类，用于存储解析结果
 * @author feng_jun_peng
 * @create 2024-12-17 16:53 
 * @version 1.0
 */
public class JavaFileInfo {
    private final String packageName;
    private final String className;
    private final String superclass;
    private final int totalLine;
    private final List<JavaMethodInfo> publicMethodInfos;
    private final List<JavaMethodInfo> protectedMethodInfos;
    private final List<JavaMethodInfo> privateMethodInfos;

    public JavaFileInfo(String packageName, String className, String superclass, int totalLine, List<JavaMethodInfo> publicMethodInfos, List<JavaMethodInfo> protectedMethodInfos, List<JavaMethodInfo> privateMethodInfos) {
        this.packageName = packageName;
        this.className = className;
        this.superclass = superclass;
        this.totalLine = totalLine;
        this.publicMethodInfos = publicMethodInfos;
        this.protectedMethodInfos = protectedMethodInfos;
        this.privateMethodInfos = privateMethodInfos;
    }

    public String getPackageName() {
        return packageName != null ? packageName : "";
    }

    public String getClassName() {
        return className != null ? className : "";
    }

    public String getSuperclass() {
        return superclass != null ? superclass : "";
    }

    public int getTotalLine() {
        return totalLine;
    }

    public List<JavaMethodInfo> getPublicMethodInfos() {
        return publicMethodInfos.isEmpty() ? new ArrayList<>() {
        } : publicMethodInfos;
    }

    public List<JavaMethodInfo> getProtectedMethodInfos() {
        return protectedMethodInfos.isEmpty() ? new ArrayList<>() {
        } : protectedMethodInfos;
    }

    public List<JavaMethodInfo> getPrivateMethodInfos() {
        return privateMethodInfos.isEmpty() ? new ArrayList<>() {
        } : privateMethodInfos;
    }

    /**
     * description: 寻找能够匹配到的方法名
     * @author: feng_jun_peng
     * @create: 2024-12-19 10:08
     * @param lineNumber: 光标当前行号
     * @return: java.lang.String
     */
    public String getMethodNameByLineNumber(int lineNumber) {
        if (lineNumber < 0)
            return null;

        for (var methodInfo : publicMethodInfos) {
            if (methodInfo.getStartLine() <= lineNumber && methodInfo.getEndLine() >= lineNumber) {
                return methodInfo.getMethodName();
            }
        }

        for (var methodInfo : protectedMethodInfos) {
            if (methodInfo.getStartLine() <= lineNumber && methodInfo.getEndLine() >= lineNumber) {
                return methodInfo.getMethodName();
            }
        }

        for (var methodInfo : privateMethodInfos) {
            if (methodInfo.getStartLine() <= lineNumber && methodInfo.getEndLine() >= lineNumber) {
                return methodInfo.getMethodName();
            }
        }
        return null;
    }

    /**
     * description: 寻找能够匹配到的方法的开始行号
     * @author: feng_jun_peng
     * @create: 2024-12-19 11:01
     * @param methodName: 匹配的方法名
     * @return: int
     */
    public int getLineNumberByMethodName(String methodName) {
        if (methodName == null || methodName.isEmpty())
            return 0;

        for (JavaMethodInfo methodInfo : publicMethodInfos) {
            if (methodName.equalsIgnoreCase(methodInfo.getMethodName())) {
                return methodInfo.getStartLine();
            }
        }
        for (JavaMethodInfo methodInfo : protectedMethodInfos) {
            if (methodName.equalsIgnoreCase(methodInfo.getMethodName())) {
                return methodInfo.getStartLine();
            }
        }
        for (JavaMethodInfo methodInfo : privateMethodInfos) {
            if (methodName.equalsIgnoreCase(methodInfo.getMethodName())) {
                return methodInfo.getStartLine();
            }
        }

        return 0;
    }

    /**
     * description: 是否存在目标方法
     * @author: feng_jun_peng
     * @create: 2024-12-19 10:45
     * @param targetMethodInfos: 目标方法集合
     * @param hitMethodName: 目标方法名（忽略大小写）
     * @return: boolean
     */
    public static boolean isExistTargetMethod(List<JavaMethodInfo> targetMethodInfos, String hitMethodName) {
        for (JavaMethodInfo existMethod : targetMethodInfos) {
            if (hitMethodName.equalsIgnoreCase(existMethod.getMethodName())) {
                return true;
            }
        }
        return false;
    }
}
